package org.study.async;

import com.google.common.collect.Lists;
import lombok.*;

import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * 业务并行处理示例。参考 https://mp.weixin.qq.com/s/f4Tp1msOSJGVz-tutCDSCw
 *
 * @author doveylovey
 * @email 1135782208@qq.com
 * @date 2022年01月06日
 */
public class CompletableFutureTest03 {
    final static AtomicLong idGen = new AtomicLong(0);

    public static void main(String[] args) {
        ProductCommon p1 = ProductCommon.builder().productId(1L).build();
        ProductCommon p2 = ProductCommon.builder().productId(2L).build();
        ProductCommon p3 = ProductCommon.builder().productId(3L).build();
        List<ProductCommon> products = Lists.newArrayList(p1, p2, p3);
        // 核心三行代码并发处理
        List<CompletableFuture<String>> prdFutures = products.stream()
                .map(i -> CompletableFuture.supplyAsync(() -> process(i), executor))
                .collect(Collectors.toList());
        List<String> prdResults = prdFutures.stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList());
        prdResults.forEach(System.out::println);
    }

    /**
     * 定义线程池
     */
    static ExecutorService executor = new ThreadPoolExecutor(3, 3, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadFactory() {
        @Override
        public Thread newThread(Runnable cmd) {
            Thread t = new Thread(cmd);
            t.setName("t-prd-" + idGen.incrementAndGet());
            return t;
        }
    });

    /**
     * 业务处理模拟
     *
     * @param product
     * @return java.lang.String
     */
    private static String process(ProductCommon product) {
        return "当前线程：" + Thread.currentThread().getName() + "，处理结果测试：" + product.getProductId();
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    static class ProductCommon {
        private Long productId;
    }
}

